package educar.models;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.LinkedList;

import educar.db.DbConnection;
import educar.db.JPA;
import educar.models.Docente;
import java.util.HashMap;
import educar.models.resolucionNotFound;

/**
 * 
 * @author Baldani-Ocejo-Padula
 * 
 * Clase que modela una resolucion, que es un trabajo que un alumno o un grupo 
 * de alumnos realiza en respuesta a una actividad propuesta por un docente.
 */
public class Resolucion
{

    private static JPA jpa = new JPA();
    private static final String noAsignado = "-1";
    private String codigo;
    private String nota;
    private Docente docente;
    private Alumno alumno;
    private Actividad actividad;


    /**
     * 
     * @param d : docente que creo la actividad
     * @param nota : calificacion que el docente le coloca a esa resolucion
     */
    public Resolucion(Docente d, String nota)
    {
        codigo = noAsignado;
        docente = d;
        this.nota = nota;
    }

    /**
     * 
     * @param codRes : codigo unico que identifica a la resolucion en sistema
     * @param dniDocente : dni del docente que creo la resolucion 
     * @param nota : calificacion que el docente le coloca a esa resolucion
     */
    private Resolucion(String codRes, String dniDocente, String nota)
    {
        codigo = codRes;
        this.nota = nota;
        try
        {
            docente = Docente.getDocenteByDni(dniDocente);
        }
        catch (docenteNotFound e)
        {
            //Todavia no esta corregida
        }
    }

    /**
     * 
     * @return verdadero si se pudo crear una persistencia en base de datos de esta 
     * resolucion, falso en caso contrario.
     */
    public boolean save()
    {
        String[] columns = { "codigoResolucion", "dniDoce", "nota" };
        PreparedStatement stm = jpa.newRecord(DbConnection.bd+".resolucion", columns);
        try
        {
            stm.setString(1, null);
            stm.setString(2, null);
            stm.setString(3,  nota);
        }
        catch (SQLException e)
        {
            e.printStackTrace();
            return false;
        }

        jpa.create(stm);
        actualizarCodigoAlMaximo();

        return true;
    }
    
    /**
     * Metodo que sirve para generar un codigo de tal forma que este sea unico en
     * la base de datos
     */
    private void actualizarCodigoAlMaximo()
    {
        ResultSet rs = jpa.showMaxColumn("resolucion", "codigoResolucion");
        try
        {
            if (rs.next())
            {
                this.codigo = rs.getString(1);
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @return devuelve la actividad para la que esta resolucion fue creada.
     */
    public Actividad getActividad()
    {
        return actividad;
    }

    /**
     * 
     * @return el alumno que confecciono la resolucion (en caso de ser una actividad
     * individual)
     */
    public Alumno getAlumno()
    {
        return alumno;
    }

    /**
     * 
     * @return el docente que creo la actividad para la cual esta resolucion fue hecha
     */
    public Docente getDocente()
    {
        return docente;
    }

    /**
     * 
     * @return el codigo de la actividad
     */
    public String getCodigo()
    {
        return codigo;
    }

    /**
     * 
     * @return la nota con la que el docente califico la actividad
     */
    public String getNota()
    {
        return nota;
    }

    /**
     * Metodo que liga la actividad que se quiere resolver a esta resolucion
     * 
     * @param actividad que se quiere ligar
     */
    public void setActividad(Actividad actividad)
    {
        this.actividad = actividad;
    }

    /**
     *  Metodo que setea el alumno que es responsable de esta resolucion.
     * 
     * @param alumno : el alumno responsable de esta resolucion
     */
    public void setAlumno(Alumno alumno)
    {
        this.alumno = alumno;
    }

    /**
     * Metodo para setear un codigo pasado por parametro a esta resolucion
     * 
     * @param codigo codigo de la resolucion
     */
    public void setCodigo(String codigo)
    {
        this.codigo = codigo;
    }

    /**
     * Metodo para setear la nota a esta resolucion
     * 
     * @param nota : nota con la que califica el docente a esta resolucion
     */
    public void setNota(String nota)
    {
        this.nota = nota;
    }

    /**
     * Metodo que setea un docente a esta actividad, pasando su dni como parametro
     * 
     * @param dniDocente dni del docente que se quiere setear
     */
    public void setDocente(String dniDocente)
    {
        try
        {
            docente = Docente.getDocenteByDni(dniDocente);
        }
        catch (docenteNotFound d)
        {
        }
    }

    /**
     * Metodo que devuelve una lista de todas las realizaciones de una actividad
     * 
     * @param Actividad actividad de las que se quieren obtener las realizaciones
     * @return una lista de realizaciones de la actividad pasada por parametro
     */
    public static LinkedList<Realizacion> getAllByActividad(Actividad a)
    {
        return getAllByActividad(a.getCodigoActividad());
    }	

    /**
     * Metodo que devuelve una lista de todas las realizaciones de una actividad
     * 
     * @param codActividad: codigo de la actividad de las que se quieren obtener las realizaciones
     * @return una lista de realizaciones de la actividad pasada por parametro
     */
    public static LinkedList<Realizacion> getAllByActividad(String codActividad)
    {
        ResultSet rs = null;
        LinkedList<Realizacion> resoluciones = new LinkedList<Realizacion>();
        rs = jpa.getByField("realiza", "codigoAct", codActividad);

        try
        {
            while (rs.next())
            {
                Realizacion r = new Realizacion(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4));
                resoluciones.add(r);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return resoluciones;
    }

    /**
     * 
     * @param codigoRes codigo de la resolucion que se esta buscando en la base de datos
     * @return una realizacion que se corresponda con el codigo de esta resolucion
     */
    public static Realizacion getRealizacionByCodigo(String codigoRes)
    {
        ResultSet rs = null;
        Realizacion r = null;

        rs = jpa.getByField("realiza", "codigoRes", codigoRes);


        try
        {
            if (rs.next())
            {
                r = new Realizacion(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4));
            }
            else
            {
                throw new resolucionNotFound();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return r;
    }

    /**
     * 
     * @param codigoRes codigo de la resolucion que se quiere obtener
     * @return un objeto de clase resolucion que tiene igual codigo de resolucion al pasado por parametro
     * @throws resolucionNotFound si no hay una resolucion con igual codigo al pasado por parametro
     */
    public static Resolucion getResolucionByCodigo(String codigoRes) throws resolucionNotFound
    {
        ResultSet rs = null;
        Resolucion r = null;

        rs = jpa.getByField("resolucion", "codigoResolucion", codigoRes);

        try
        {
            if (rs.next())
            {
                r = new Resolucion(rs.getString(1), rs.getString(2), rs.getString(3));
            }
            else
            {
                throw new resolucionNotFound();
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }

        return r;
    }


    /**
     * 
     * @param codActividad codigo de la actividad de la cual se quiere obtener las resoluciones
     * @return un arreglo de resoluciones correspondientes a una actividad en representacion de string
     */
    public static String[] getAllResByActividadArray(String codActividad)
    {
        LinkedList<Realizacion> r = getAllByActividad(codActividad);
        String[] resoluciones = new String[r.size()];
        for (int i = 0; i < r.size(); i++)
        {
            resoluciones[i] = r.get(i).toString(); //VER el toString deberia ser de Resolucion, no de Realiza
        }
        return resoluciones;
    }
    
    /**
     * 
     * @param actividad de la cual se quiere obtener las resoluciones
     * @return un arreglo de resoluciones correspondientes a una actividad en representacion de string
     */
    public static String[] getAllByActividadArray(Actividad actividad)
    {
        return getAllResByActividadArray(actividad.getCodigoActividad());
    }


    /**
     * Metodo que actualiza la base de datos con los datos actuales de esta resolucion
     */
    public void update()
    {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("dniDoce", docente.getDni());
        map.put("nota", nota);
        jpa.genericUpdate("resolucion", map, "codigoResolucion", codigo);

    }

}
